#include <stdio.h>

int main(int argc, const char *argv[])
{
	int s[5] = {10, 20, 30, 40, 50};
	
	// 数组名就是数组的首地址
	// 且操作空间是一个数组元素的大小
	printf("s = %p\n", s); // 相差4字节 1个元素
	printf("s+1 = %p\n", s+1);

	// 数组名[下标]  访问元素的本质
	// 就是基于数组首地址和偏移量取*操作
	printf("s[0] = %d  *s = %d\n", s[0], *s); // 10 10
	printf("s[1] = %d  *(s+1) = %d\n", s[1], *(s+1)); // 20 20
	// 也就是说  s[i] <==> *(s+i)
	
	// 也可以定义一个指针来保存数组的首地址
	// 一般情况下为了操作空间一致  我们都定义和数组同类型的指针
	// 指针保存数组首地址有下面三种写法:
	int *p1 = s;		// --最常用的写法
	int *p2 = &s[0];	// --写着麻烦  一般不用
	//int *p3 = &s;		// 对数组名取地址相当于给指针升维 这种写法一般不使用
	// 从数值 和 使用方式上 p1 p2 p3 一模一样 但是不推荐使用第三种写法
	printf("p1 = %p\n", p1);
	printf("p2 = %p\n", p2);
	//printf("p3 = %p\n", p3);

	// 指针保存了数组首地址之后 通过指针也可以访问数组元素了
	int *p = s;
	// 指针保存了数组首地址之后 有下面的等价关系
	// s[i] <==> *(s+i) <==> p[i] <==> *(p+i)
	
	// 一维数组的遍历
	int i = 0;
	for(i = 0; i < 5; i++){
		//printf("%d ", s[i]);
		//printf("%d ", *(s+i));
		//printf("%d ", p[i]);
		printf("%d ", *(p+i));
	}
	printf("\n");

	printf("----------------------------------\n");

	// 数组名 s 和 指针 p 区别？
	// 1.sizeof(数组名) 数组总大小   sizeof(指针) 指针的大小(固定的)
	// 2.s是数组名 是常量 不能被赋值 不能 ++   而指针p是变量
	for(i = 0; i < 5; i++){
		#if 1
		// 正确的
		printf("%d ", *p);
		p++;
		#else
		// 错误的 s 不支持++
		printf("%d ", *s);
		s++;
		#endif
	}
	printf("\n");

	return 0;
}
